import React, { useCallback, useImperativeHandle, useRef } from 'react';
import { Input } from 'antd';
import { size } from 'lodash';
import cn from 'classnames';
import ReactDom from 'react-dom';
import styles from './index.less';

/**
 * @description 显示输入字数的输入框
 * @param {*} suffix 输入框组件后缀
 * @param {Number} maxLength 输入框可输入的最大安全值，上限后不可输入
 * @param {Number} overStep 输入框可输入的最大长度，超出字体颜色会变红
 * @param {String} separator 分隔符
 * @param {Booblean} area 输出TextArea类型
 * @param {Booblean} areaTextOut TextArea数字显示在外部
 * @param {Booblean} showNumber 是否显示字数
 */
const LimitInput = React.forwardRef(
    ({ suffix, overStep, separator = '/', area, areaTextOut, showNumber = true, inputRef, ...rest }, ref) => {
        const maxLen = rest?.maxLength || 500;
        const valueSize = size(rest?.value);
        const text = `${valueSize}${separator}${overStep || maxLen}`;
        const textClassName = cn(styles.textColor, valueSize > (overStep || maxLen) ? styles.red : '');
        const cRef = useRef();
        const handleSelectionRange = useCallback(input => {
            if (!area) return; // textarea才需要重新定位光标位置
            // eslint-disable-next-line react/no-find-dom-node
            const inputDom = ReactDom.findDOMNode(input);
            if (inputDom.setSelectionRange) {
                // 非ie
                inputDom.focus(); // 获取焦点
                inputDom.setSelectionRange(-1, -1); // 设置选定区的开始和结束点
            } else if (inputDom.createTextRange) {
                const range = inputDom.createTextRange(); // 创建选定区
                range.collapse(true); // 设置为折叠,即光标起点和结束点重叠在一起
                range.moveEnd('character', -1); // 移动结束点
                range.moveStart('character', -1); // 移动开始点
                range.select(); // 选定当前区域
            }
        }, [inputRef]);
        useImperativeHandle(inputRef, () => ({
            focus: () => {
                const input = cRef?.current;
                if (input) {
                    // eslint-disable-next-line no-unused-expressions
                    input.focus();
                    handleSelectionRange(input);
                }
            }
        }), [inputRef, cRef]);
        return (
            <div className={styles.limitInputWrap} ref={ref}>
                {area ? (
                    <div className={styles.textAreaWrap}>
                        <Input.TextArea ref={cRef} {...rest} style={{ paddingBottom: 24, ...rest?.style }} />
                        {showNumber === true && (
                            <span
                                className={cn(
                                    areaTextOut ? styles.areaTextOut : '',
                                    rest?.disabled ? styles.disabled : '',
                                    textClassName
                                )}
                            >
                                {text}
                            </span>
                        )}
                    </div>
                ) : (
                    <Input
                        {...rest}
                        ref={cRef}
                        suffix={
                            <>
                                {suffix || ''}
                                {showNumber === true && (
                                    <span className={textClassName} style={{ marginLeft: 5, ...rest?.style }}>
                                        {text}
                                    </span>
                                )}
                            </>
                        }
                    />
                )}
            </div>
        );
    }
);

LimitInput.displayName = 'LimitInput'

export default LimitInput;
